package com.bkgy.controller.stripsteel.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.commom.model.PageParams;
import com.bkgy.commom.model.QueryDTO;
import com.bkgy.controller.stripsteel.domain.*;
import com.bkgy.controller.stripsteel.domain.dto.StripSteelDto;
import com.bkgy.controller.stripsteel.mapper.PaoPianMapper;
import com.bkgy.controller.stripsteel.mapper.StriSteelMapper;
import com.bkgy.controller.stripsteel.mapper.TPdoDataL3Cal1630Mapper;
import com.bkgy.controller.stripsteel.service.StripSteelService;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import com.bkgy.util.ExcelUtilsPOI;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 实际跑偏预测服务实现类
 */
@Service
@RequiredArgsConstructor
public class StripSteelServiceImpl extends ServiceImpl<StriSteelMapper, TbPaopianPdoData> implements StripSteelService {
    private final PaoPianMapper paoPianMapper;
    private final TPdoDataL3Cal1630Mapper tPdoDataL3Cal1630Mapper;

    @Override
    public ResultData findStripSteelByPage(QueryDTO<StripSteelDto> queryDTO) {
        dealWithParam(queryDTO);
        List<TbPaopianPdoData> records = baseMapper.findStripSteels(
                queryDTO.getPage().getPageIndex(),
                queryDTO.getPage().getPageSize(),
                queryDTO.getDto()
        );
        Map<String, Object> data = new HashMap<>();
        Long total = baseMapper.countStripSteels(queryDTO.getDto());
        data.put("records", records);
        data.put("total", total.intValue());
        return ResultData.ResultDataSuccess(data, total.intValue());
    }

    @Override
    public void aosrpeExcel(QueryDTO<StripSteelDto> param, HttpServletResponse response) {
        List<ExcelStripSteel> list = new ArrayList<>();
        dealWithParam(param);
        PageParams p = param.getPage();
        p.setPageSize(Integer.MAX_VALUE);
        List<TbPaopianPdoData> records = baseMapper.findStripSteels(p.getPageIndex(),p.getPageSize(),param.getDto());
        for (TbPaopianPdoData obj : records) {
            ExcelStripSteel excel = new ExcelStripSteel();
            BeanUtils.copyProperties(obj, excel);
            Date prodTime = DateUtil.getStringToDate("yyyyMMddHHmmss",excel.getProdEndTime());
            excel.setProdEndTime(DateUtil.getDateToString(prodTime,"yyyy-MM-dd HH:mm:ss"));

            list.add(excel);
        }
        try {
            Map<String, Object> dataMap = new HashMap();
            dataMap.put("data", list);
            File file = ResourceUtils.getFile("classpath:exceltemplate\\生产实际跑偏列表.xlsx");
            TemplateExportParams templ = new TemplateExportParams(file.getPath(), false);
            Workbook workbook = ExcelExportUtil.exportExcel(templ, dataMap);
            ExcelUtilsPOI.exportExcel("生产实际跑偏列表", response, workbook);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void dealWithParam(QueryDTO<StripSteelDto> queryDTO) {
        StripSteelDto dto = queryDTO.getDto();
        Integer pageIndex = queryDTO.getPage().getPageIndex();
        Integer pageSize = queryDTO.getPage().getPageSize();

        // 处理时间格式
        if (!StringUtils.isEmpty(dto.getStartTime())) {
            String startTime = dto.getStartTime().replaceAll("[^0-9]", "");
            dto.setStartTime(startTime.substring(0, 14));
        }
        if (!StringUtils.isEmpty(dto.getEndTime())) {
            String endTime = dto.getEndTime().replaceAll("[^0-9]", "");
            dto.setEndTime(endTime.substring(0, 14));
        }
        queryDTO.getPage().setPageIndex(pageIndex - 1);
    }

    public ResultData getSteelInfo(List<String> coilIds) {
        // 1. 参数校验
        if (coilIds == null || coilIds.isEmpty()) {
            return ResultData.ResultDataFaultSelf("钢卷信息不能为空", null);
        }

        // 2. 使用并行查询提高效率
        List<PaoPianPDI> paopianInfo = new ArrayList<>();
        List<TPdiDataL3Cal1630> dataCal1630s = new ArrayList<>();
        List<SteelInfo> result = new ArrayList<>();

        try {
            // 并行查询两个数据源
            CompletableFuture<List<PaoPianPDI>> paopianFuture = CompletableFuture.supplyAsync(() -> {
                LambdaQueryWrapper<PaoPianPDI> wrapper = new LambdaQueryWrapper<>();
                wrapper.in(PaoPianPDI::getEntId, coilIds);
                return paoPianMapper.selectList(wrapper);
            });

            CompletableFuture<List<TPdiDataL3Cal1630>> calFuture = CompletableFuture.supplyAsync(() -> {
                LambdaQueryWrapper<TPdiDataL3Cal1630> pdoWrapper = new LambdaQueryWrapper<>();
                pdoWrapper.in(TPdiDataL3Cal1630::getEntid, coilIds);
                return tPdoDataL3Cal1630Mapper.selectList(pdoWrapper);
            });

            // 等待两个查询完成
            paopianInfo = paopianFuture.get();
            dataCal1630s = calFuture.get();

            // 3. 创建数据映射提高查找效率
            Map<String, TPdiDataL3Cal1630> calDataMap = dataCal1630s.stream()
                    .collect(Collectors.toMap(
                            TPdiDataL3Cal1630::getEntid,
                            Function.identity(),
                            (existing, replacement) -> existing // 处理重复键
                    ));
            // 4. 创建结果列表并填充数据
            for (PaoPianPDI paopian : paopianInfo) {
                SteelInfo steelInfo = new SteelInfo();
                BeanUtils.copyProperties(paopian, steelInfo);
                // 从映射中获取补充数据
                TPdiDataL3Cal1630 calData = calDataMap.get(paopian.getEntId());
                if (calData != null) {
                    steelInfo.setWidth(calData.getInMatWidth());
                    steelInfo.setThickness(calData.getInMatThk());
                    steelInfo.setSteelGrade(calData.getSteelGrade());
                } else {
                    // 设置默认值或保留null
                    steelInfo.setWidth(null);
                    steelInfo.setThickness(null);
                    steelInfo.setSteelGrade(null);
                }
                result.add(steelInfo);
            }
            return ResultData.ResultDataSuccess(result);
        } catch (InterruptedException | ExecutionException e) {
            Thread.currentThread().interrupt();
            return ResultData.ResultDataFaultSelf("查询中断: " + e.getMessage(), null);
        } catch (Exception e) {
            log.error("获取钢卷信息失败", e);
            return ResultData.ResultDataFaultSelf("系统错误: " + e.getMessage(), null);
        }
    }


}
